package com.javasea.netty.har.server.netty;

import com.javasea.netty.har.common.endec.CustomProtobufDecoder;
import com.javasea.netty.har.common.endec.CustomProtobufEncoder;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName: PtinterServerChannelInitializer
 * @Author: huangzf
 * @Date: 2018/8/1 12:01
 * @Description:
 */
@Slf4j
public class PtinterServerChannelInitializer extends ChannelInitializer<SocketChannel> {

    private PrinterServerHandler handler ;

    @Override
    protected void initChannel(SocketChannel socketChannel) {
        ChannelPipeline pipeline = socketChannel.pipeline();
        //解决TCP粘包拆包的问题，以特定的字符结尾（$_）
        //pipeline.addLast(new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Unpooled.copiedBuffer(CommonConstant.END_STR.getBytes())));

        // proto自定义编码解码器 https://www.cnblogs.com/Binhua-Liu/p/5577622.html
        // ProtobufVarint32LengthFieldPrepender：因为ProtobufEncoder只是将message的各个filed按照规则输出了，并没有serializedSize，所以socket无法判定package（封包）。这个Encoder的作用就是在ProtobufEncoder生成的字节数组前，prepender一个varint32数字，表示serializedSize。
        // ProtobufVarint32FrameDecoder：这个decoder和Prepender做的工作正好对应，作用就是“成帧”，根据seriaziedSize读取足额的字节数组--一个完整的package。
        pipeline.addLast(new ProtobufVarint32FrameDecoder());
        pipeline.addLast("decoder",new CustomProtobufDecoder());
        pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
        pipeline.addLast("encoder",new CustomProtobufEncoder());

        // 对象编码解码
//        pipeline.addLast("decoder", new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers
//            .weakCachingConcurrentResolver(this.getClass().getClassLoader())));
//        pipeline.addLast("encoder", new ObjectEncoder());

        // 默认的Protobuf只能对一个Proto类进行编解码，不太适用
//        MessageLite aa = CmdBatchProto.CmdBatch.getDefaultInstance();
//        pipeline.addLast(new ProtobufDecoder(aa));
//        pipeline.addLast(new ProtobufEncoder());
        pipeline.addLast(new IdleStateHandler(10,0,0,TimeUnit.SECONDS));
        //服务器的逻辑
        pipeline.addLast("handler", new PrinterServerHandler());
    }

//    public void resetSync(CountDownLatch latch, int rec){
//        handler.resetSync(latch, rec);
//    }
//
//    public Object getResult(){
//        return handler.getResult();
//    }


}
